package com.nbjtjc.safe.service.safe;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.nbjtjc.common.bean.INSPECTTYPEENUM;
import com.nbjtjc.common.bean.PLANFREQUENCY;
import com.nbjtjc.common.bean.TASKSTATUS;
import com.nbjtjc.safe.bean.Constant;
import com.nbjtjc.safe.bean.Result;
import com.nbjtjc.safe.mapper.danger.DangerInspectListPublicMapper;
import com.nbjtjc.safe.mapper.danger.DangerInspectMapper;
import com.nbjtjc.safe.mapper.danger.DangerInspectPublicMapper;
import com.nbjtjc.safe.mapper.safe.*;
import com.nbjtjc.safe.mapper.sys.SysFileMapper;
import com.nbjtjc.safe.model.danger.DangerInspectPublic;
import com.nbjtjc.safe.model.safe.*;
import com.nbjtjc.safe.model.sys.SysFile;
import com.nbjtjc.safe.util.FREQUENCYENUM;
import com.nbjtjc.safe.util.MyShiroUtils;
import io.swagger.models.auth.In;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class SafeDangerInspectTaskServiceImpl {

    @Autowired
    private SafeDangerInspectPlanMapper safeDangerInspectPlanMapper;

    @Autowired
    private SafeDangerInspectTaskMapper safeDangerInspectTaskMapper;

    @Autowired
    private DangerInspectPublicMapper inspectPublicMapper;
    @Autowired
    private DangerInspectMapper inspectMapper;

    @Autowired
    private DangerInspectListPublicMapper listPublicMapper;
    @Autowired
    private SafeInspectTablePublicServiceImpl tablePublicService;

    @Autowired
    private SysFileMapper sysFileMapper;

    @Autowired
    private SafeDangerInspectTaskRecordMapper recordMapper;

    @Autowired
    private SafeEnterpriseMapper enterpriseMapper;

    @Autowired
    private SafeUserPlanMapper safeUserPlanMapper;

    @Autowired
    private SafeEnterprisePlanMapper safeEnterprisePlanMapper;
    @Value("${aliyun.oss.domain}")
    private String ossDomain;

    public Result getTaskInfo() {
        Result result = new Result();
        SafeDangerInspectTask task = new SafeDangerInspectTask();
        task.setTaskStatus(TASKSTATUS.STARTING.getCode());
        task.setCreateUserId(MyShiroUtils.getSessionUserId());
        int startingCount = safeDangerInspectTaskMapper.selectCount(task);
        task.setTaskStatus(TASKSTATUS.UNSTART.getCode());
        int unstartCount = safeDangerInspectTaskMapper.selectCount(task);
        task.setTaskStatus(TASKSTATUS.OVER.getCode());
        int overCount = safeDangerInspectTaskMapper.selectCount(task);
        task.setTaskStatus(TASKSTATUS.PLAN.getCode());
        int planCount = safeDangerInspectTaskMapper.selectCount(task);

        Map<String, Integer> countInfo = new HashMap<>();
        countInfo.put("starting", startingCount);
        countInfo.put("unstart", unstartCount);
        countInfo.put("over", overCount);
        countInfo.put("plan", planCount);
        result.setData(countInfo);
        return result;
    }

    public Result search(SafeDangerInspectTask task) {
        Result result = new Result();
        PageHelper.startPage(task.getPageCurrent()
                , task.getPageSize());
        if (StringUtils.isEmpty(task.getTaskName())) {
            task.setTaskName(null);
        }
        List<SafeDangerInspectTask> taskList = safeDangerInspectTaskMapper.search(task);
        taskList.forEach(safeTask -> {
            safeTask.setTaskStatusStr(TASKSTATUS.getName(safeTask.getTaskStatus()));
            safeTask.setInspectTypeStr(INSPECTTYPEENUM.getName(safeTask.getInspectType()));
            safeTask.setFrequencyStr(FREQUENCYENUM.getName(safeTask.getFrequency()));
        });
        if (CollectionUtil.isNotEmpty(taskList)) {
            compareTaskPic(taskList);
        }
        result.setData(new PageInfo<>(taskList));
        return result;
    }

    private void compareTaskPic(List<SafeDangerInspectTask> taskList) {
        List<Integer> taskIds = taskList.parallelStream()
                .map(SafeDangerInspectTask::getId).collect(Collectors.toList());
        List<SysFile> sysFiles = sysFileMapper.findByContentIds(taskIds, Constant.SysFileType.TASK_FILE.getValue());
        Map<Integer, SafeDangerInspectTask> idMap = taskList.stream().collect(Collectors.toMap(SafeDangerInspectTask::getId, task -> task));
        sysFiles.forEach(sysFile -> {
            sysFile.setUrl(ossDomain + "/" + sysFile.getPath() + "?x-oss-process=image/resize,m_fixed,h_70,w_70");
            sysFile.setOriUrl(ossDomain + "/" + sysFile.getPath());
            idMap.get(sysFile.getContentId()).getTaskPics().add(sysFile);
        });
    }

    /**
     * 单独生成检查任务时，跟检查计划没有关联
     * @param task
     * @return
     */
    @Transactional
    public Result add(SafeDangerInspectTask task) {
        Result result = new Result();
        SafeDangerInspectPlan plan = safeDangerInspectPlanMapper.selectByPrimaryKey(task.getInspectPlanId());
        if (task.getStartTime().getTime() < new Date().getTime()) {
            task.setTaskStatus(TASKSTATUS.UNSTART.getCode());
        } else {
            task.setTaskStatus(TASKSTATUS.PLAN.getCode());
        }
        task.setCreateTime(new Date());
        //todo 生成
//        task.setInspectUser(plan.getInspectUser());
        task.setInspectUserId(plan.getInspectUserId());
        task.setInspectExplain(plan.getInspectExplain());
        task.setPlanName(plan.getName());
        task.setEnterpriseId(plan.getEnterpriseId());
        task.setEnterpriseName(plan.getEnterpriseName());
        task.setCreateUser(MyShiroUtils.getSessionUserName());
        task.setCreateUserId(MyShiroUtils.getSessionUserId());
        safeDangerInspectTaskMapper.insertSelective(task);
        List<SafeDangerInspectTask> taskList = new ArrayList<>();
        taskList.add(task);
        publicTaskInDays(taskList, 3, task.getInspectPlanId());
        return result;
    }

    public Result update(SafeDangerInspectTask task) {
        Result result = new Result();
        safeDangerInspectTaskMapper.updateByPrimaryKeySelective(task);
        return result;
    }



    public void generateTaskByEnterprise(List<DangerInspectPublic> dangerInspectPublicList
            ,SafeDangerInspectPlan safePlan,int createUserId,SafeEnterprisePlan enterprisePlan){
        //创建企业的任务
        SafeDangerInspectTask task = new SafeDangerInspectTask();
        task.setStartTime(safePlan.getStartTime());
        task.setEndTime(safePlan.getEndTime());
        task.setFrequency(safePlan.getFrequency());
        if (createUserId == 0) {
            task.setCreateUserId(safePlan.getCreateUserId());
        } else {
            task.setCreateUserId(createUserId);
        }
//        task.setInspectUserId(safePlan.getInspectUserId());
        task.setCreateUser(safePlan.getCreateUser());
//        task.setInspectUser(safePlan.getInspectUser());
        task.setInspectPlanId(safePlan.getId());
        task.setInspectType(safePlan.getInspectType());
        task.setInspectExplain(safePlan.getInspectExplain());
        task.setPlanName(safePlan.getName());
        task.setTaskName(safePlan.getName() + "-" + DateUtil.format(new Date(), "yyyyMMdd"));
        task.setCreateTime(new Date());
        task.setEnterpriseId(enterprisePlan.getEnterpriseId());
        SafeEnterprise safeEnterprise=enterpriseMapper.selectByPrimaryKey(enterprisePlan.getEnterpriseId());
        task.setEnterpriseName(safeEnterprise.getName());
        safeDangerInspectTaskMapper.insertSelective(task);
        dangerInspectPublicList.forEach(tablePublic -> {
            tablePublic.setId(tablePublic.getInspectId());
            tablePublic.setInspectTaskId(task.getId());
        });
        tablePublicService.publicTables(dangerInspectPublicList, safePlan, createUserId, false);
    }

    public void generateEnterpriseTaskByPlan(Integer planId,int createUserId){
        SafeDangerInspectPlan safePlan = safeDangerInspectPlanMapper.selectByPrimaryKey(planId);
        if (ObjectUtil.isNull(safePlan)) {
            return ;
        }
        //查询plan的检查表
        DangerInspectPublic dangerInspectPublic = new DangerInspectPublic();
        dangerInspectPublic.setInspectPlanId(planId);
        List<DangerInspectPublic> dangerInspectPublicList = inspectPublicMapper.select(dangerInspectPublic);

        Example example=new Example(SafeEnterprisePlan.class);
        example.createCriteria().andEqualTo("planId",planId);
        List<SafeEnterprisePlan> safeEnterprisePlanList=safeEnterprisePlanMapper.selectByExample(example);
        if(CollectionUtil.isNotEmpty(safeEnterprisePlanList)){
            safeEnterprisePlanList.forEach(safeEnterprisePlan -> {
                this.generateTaskByEnterprise(dangerInspectPublicList
                        ,safePlan,createUserId,safeEnterprisePlan);
            });
        }
    }


    public boolean generateTaskByPlan(Integer planId, int createUserId) {
        SafeDangerInspectPlan safePlan = safeDangerInspectPlanMapper.selectByPrimaryKey(planId);
        if (ObjectUtil.isNull(safePlan)) {
            return false;
        }
        SafeDangerInspectTask task = new SafeDangerInspectTask();
        task.setStartTime(safePlan.getStartTime());
        if (safePlan.getFrequency().equals(PLANFREQUENCY.NOREPEAT.getCode())) {
            task.setEndTime(safePlan.getEndTime());
        } else {
            Date endTime = new Date(safePlan.getStartTime().getTime() + PLANFREQUENCY.getTimeInterval(safePlan.getFrequency()) * 1000);
            task.setEndTime(endTime);
        }
        task.setEndTime(safePlan.getEndTime());
        task.setFrequency(safePlan.getFrequency());
        if (createUserId == 0) {
            task.setCreateUserId(safePlan.getCreateUserId());
        } else {
            task.setCreateUserId(createUserId);
        }
        task.setInspectUserId(safePlan.getInspectUserId());
        task.setCreateUser(safePlan.getCreateUser());
        task.setInspectUser(safePlan.getInspectUser());
        task.setInspectPlanId(safePlan.getId());
        task.setInspectType(safePlan.getInspectType());
        task.setInspectExplain(safePlan.getInspectExplain());
        task.setPlanName(safePlan.getName());
        task.setTaskName(safePlan.getName() + "-" + DateUtil.format(new Date(), "yyyyMMdd") + "-" + safePlan.getInspectUser());
        task.setCreateTime(new Date());
        task.setEnterpriseId(safePlan.getEnterpriseId());
        task.setEnterpriseName(safePlan.getEnterpriseName());
        safeDangerInspectTaskMapper.insertSelective(task);
        DangerInspectPublic dangerInspectPublic = new DangerInspectPublic();
        dangerInspectPublic.setInspectPlanId(planId);
        List<DangerInspectPublic> tablePublicList = inspectPublicMapper.select(dangerInspectPublic);
        tablePublicList.forEach(tablePublic -> {
            tablePublic.setId(tablePublic.getInspectId());
            tablePublic.setInspectTaskId(task.getId());
        });
        tablePublicService.publicTables(tablePublicList, safePlan, createUserId, false);
        return true;
    }

    @Transactional
    public Result publicTaskPlan(SafeDangerInspectTask task) {
        Result result = new Result();
        task.setTaskStatus(TASKSTATUS.UNSTART.getCode());
        safeDangerInspectTaskMapper.updateByPrimaryKeySelective(task);
        DangerInspectPublic dangerInspectPublic = new DangerInspectPublic();
        dangerInspectPublic.setInspectPlanId(task.getInspectPlanId());
        List<DangerInspectPublic> tablePublicList = inspectPublicMapper.select(dangerInspectPublic);
        if (CollectionUtil.isNotEmpty(tablePublicList)) {
            tablePublicList.forEach(tablePublic -> {
                tablePublic.setInspectTaskId(task.getId());
            });
            SafeDangerInspectPlan safePlan = safeDangerInspectPlanMapper.selectByPrimaryKey(task.getInspectPlanId());
            tablePublicService.publicTables(tablePublicList, safePlan, task.getCreateUserId(), false);
        }
        return result;
    }

    public List<SafeDangerInspectTask> gengerateTaskPlan(Integer safePlanId, Integer createUserId, String username, List<SafeDangerInspectTask> planTaskList) {
        if (CollectionUtil.isNotEmpty(planTaskList)) {
            SafeDangerInspectPlan safePlan = safeDangerInspectPlanMapper.selectByPrimaryKey(safePlanId);
            SafeEnterprise enterprise = enterpriseMapper.selectByPrimaryKey(safePlan.getEnterpriseId());
            planTaskList.forEach(task -> {
                task.setEnterpriseName(enterprise.getName());
                task.setEnterpriseId(enterprise.getId());
                task.setCreateUserId(createUserId);
                task.setCreateUser(username);
                task.setInspectPlanId(safePlanId);
                task.setInspectUser(safePlan.getInspectUser());
                task.setInspectUserId(safePlan.getInspectUserId());
                task.setInspectType(safePlan.getInspectType());
                task.setInspectExplain(safePlan.getInspectExplain());
                task.setPlanName(safePlan.getName());
                task.setFrequency(safePlan.getFrequency());
                task.setWeekend(safePlan.getWeekend());
                task.setAhead(safePlan.getAhead());
                task.setAheadUnit(safePlan.getAheadUnit());
                task.setTaskStatus(TASKSTATUS.PLAN.getCode());
                task.setCreateTime(new Date());
                safeDangerInspectTaskMapper.insertSelective(task);
            });
        }
        return planTaskList;
    }

    public boolean publicTaskInDays(List<SafeDangerInspectTask> taskList, int day, int safePlanId) {
        long startTime = new Date().getTime() + day * 24 * 3600 * 1000;
        List<SafeDangerInspectTask> taskToPublic = new ArrayList<>();
        SafeDangerInspectPlan safePlan = safeDangerInspectPlanMapper.selectByPrimaryKey(safePlanId);
        DangerInspectPublic dangerInspectPublic = new DangerInspectPublic();
        dangerInspectPublic.setInspectPlanId(safePlanId);
        List<DangerInspectPublic> tablePublicList = inspectPublicMapper.select(dangerInspectPublic);

        taskList.forEach(task -> {
            if (task.getStartTime().getTime() < startTime) {
                task.setTaskStatus(TASKSTATUS.UNSTART.getCode());
                safeDangerInspectTaskMapper.updateByPrimaryKeySelective(task);
                tablePublicList.forEach(tablePublic -> {
                    tablePublic.setInspectTaskId(task.getId());
                });
                if (CollectionUtil.isNotEmpty(tablePublicList)) {
                    tablePublicService.publicTables(tablePublicList, safePlan, task.getCreateUserId(), false);
                }
            }
        });
        return true;
    }

    public Result addTaskTable(DangerInspectPublic inspectPublic) {
        Result result = new Result();
        SafeDangerInspectPlan plan = safeDangerInspectPlanMapper.selectByPrimaryKey(inspectPublic.getInspectPlanId());
        List<DangerInspectPublic> dangerInspectPublicList = new ArrayList<>();
        dangerInspectPublicList.add(inspectPublic);
        tablePublicService.publicTables(dangerInspectPublicList, plan, MyShiroUtils.getSessionUserId(), false);
        result.setData(inspectPublic);
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    public Result deleteTaskTable(int inspectPublicId) {
        Result result = new Result();
        inspectPublicMapper.deleteByPrimaryKey(inspectPublicId);
        listPublicMapper.deleteByInspectPublicId(inspectPublicId);
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    public Result deleteTaskByPlanId(int planId) {
        Result result = new Result();
        List<Integer> taskIds = safeDangerInspectTaskMapper.selectIdsByPlanId(planId);
        safeDangerInspectTaskMapper.deleteByPlanId(planId);
        if (CollectionUtil.isNotEmpty(taskIds)) {
            taskIds.forEach(taskId -> {
                recordMapper.deleteByTaskId(taskId);
                inspectPublicMapper.deleteByTaskId(taskId);
            });
        }
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    public Result delete(int taskId) {
        Result result = new Result();
        safeDangerInspectTaskMapper.deleteByPrimaryKey(taskId);
        recordMapper.deleteByTaskId(taskId);
        inspectPublicMapper.deleteByTaskId(taskId);
        return result;
    }

}
